package com.liu.stockmarket.ui.detail

import androidx.lifecycle.*
import com.liu.stockmarket.model.ResponseResult
import com.liu.stockmarket.model.Stock
import com.liu.stockmarket.model.StockDetailAndProfit
import com.liu.stockmarket.repository.database.StockRepository
import com.liu.stockmarket.repository.database.TransactionRecordRepository
import com.liu.stockmarket.repository.database.entity.StockEntity
import com.liu.stockmarket.repository.database.entity.TransactionRecordEntity
import com.liu.stockmarket.repository.network.EasyMoneyRepository
import com.liu.stockmarket.utils.StockTransactionUtil
import com.liu.stockmarket.utils.diffToStockTransaction
import com.liu.stockmarket.utils.toStockSecids
import com.liu.stockmarket.utils.toStockTransactionInfo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.lang.IllegalArgumentException
import java.time.LocalDate

class DetailViewModel(
    private val transactionRecordRepository: TransactionRecordRepository,
    private val stockRepository: StockRepository,
    private val easyMoneyRepository: EasyMoneyRepository,
    private val stockId: Long
) : ViewModel() {


    private val _result = MutableLiveData<ResponseResult<StockDetailAndProfit>>()
    val result: LiveData<ResponseResult<StockDetailAndProfit>> = _result

    val allStockList = stockRepository.allStock.asLiveData()
    val holdingStockList = stockRepository.holdingStock.asLiveData()

    val allTransactionRecords = transactionRecordRepository.queryByStockId(stockId).asLiveData()

    private val _stock = MutableLiveData<StockEntity>()
    var stock: LiveData<StockEntity> = _stock

    fun parse(transactionRecords: List<TransactionRecordEntity>) {


        viewModelScope.launch(Dispatchers.IO) {
            val stock = stockRepository.queryById(stockId)
                ?: throw IllegalArgumentException("没有这个股票：${stockId}")

            _stock.postValue(stock)


            val transactionInfo = if (stock.stockType == Stock.StockType.FUND) {
                val fundTransactionInfo = easyMoneyRepository.getFundTransactionInfo(stock.code)
                if (fundTransactionInfo?.Datas == null) {
                    null
                } else {
                    fundTransactionInfo.Datas.toStockTransactionInfo()[0]
                }

            } else {
                val stockTransactionInfo =
                    easyMoneyRepository.getStockTransactionInfo(stock.toStockSecids())
                if (stockTransactionInfo?.data == null || stockTransactionInfo.data.total == 0) {
                    null
                } else {
                    stockTransactionInfo.data.diff.diffToStockTransaction()[0]
                }

            }


            val profit = if (transactionInfo != null) {
                StockTransactionUtil.parseProfit(
                    stock = stock,
                    transactionInfo = transactionInfo,
                    transactionRecordRepository.queryTodayTransactionRecordByStockId(
                        stockId,
                        LocalDate.now()
                    )
                )
            } else {
                StockDetailAndProfit.Profit(
                    stock.holdingPrice * stock.holdingNumber
                )
            }

            val stockDetailAndProfit = StockDetailAndProfit(
                profit, transactionRecords.size,
                transactionRecords.sumOf {
                    it.handlingFee
                }, toItem(transactionRecords)
            )

            _result.postValue(ResponseResult.success(stockDetailAndProfit))

        }

    }

    private fun toItem(transactionRecords: List<TransactionRecordEntity>): List<DetailAdapter.Item> {
        return transactionRecords.map {
            DetailAdapter.Item(
                it.transactionType,
                it.transactionDate,
                it.transactionNumber * it.transactionPrice,
                it.handlingFee,
                it.transactionPrice,
                it.transactionNumber
            )
        }.toList()
    }

    class DetailViewModelFactory(
        private val transactionRecordRepository: TransactionRecordRepository,
        private val stockRepository: StockRepository,
        private val easyMoneyRepository: EasyMoneyRepository,
        private val stockId: Long
    ) :
        ViewModelProvider.Factory {
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            @Suppress("UNCHECKED_CAST")
            return DetailViewModel(
                transactionRecordRepository,
                stockRepository,
                easyMoneyRepository, stockId
            ) as T
        }

    }
}